package com.swinw.asumall.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.swinw.asumall.cart.fegin.ProductFeignService;
import com.swinw.asumall.cart.interceptor.CartInterceptor;
import com.swinw.asumall.cart.service.CartService;
import com.swinw.asumall.cart.vo.Cart;
import com.swinw.asumall.cart.vo.CartItem;
import com.swinw.asumall.cart.vo.SkuInfoVo;
import com.swinw.asumall.cart.vo.UserInfoVo;
import com.swinw.common.utils.R;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {


    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ThreadPoolExecutor executor;

    @Autowired
    ProductFeignService productFeignService;


    private final String CART_PREFIX="swinw:cart:";

    /**
     * 添加商品到购物
     * @param skuId
     * @param num
     * @return
     */
    @Override
    public CartItem addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> operations = getCart();

        //查看当前的购物车中是否已经存在当前的商品
        String cart = (String) operations.get(skuId + "");
        if(!StringUtils.isEmpty(cart)){//如果获取的数据存在，那么缓存中存在当前的商品信息
            CartItem cartItem = JSON.parseObject(cart, new TypeReference<CartItem>() {});
            cartItem.setCount(cartItem.getCount()+num);
            String itemString = JSON.toJSONString(cartItem);
            operations.put(skuId+"",itemString);
            return cartItem;
        }

        CartItem item = new CartItem();
        //1、远程查询当前需要添加的商品信息
        CompletableFuture<Void> skuInfoFuture = CompletableFuture.runAsync(() -> {
            R skuInfo = productFeignService.getSkuInfo(skuId);
            LinkedHashMap<String,Object> skuInfoVo = (LinkedHashMap<String, Object>) skuInfo.get("skuInfo");
            item.setCheck(true);
            item.setSkuId(skuId);
            item.setCount(num);
            item.setImage((String) skuInfoVo.get("skuDefaultImg"));
            item.setPrice(new BigDecimal(skuInfoVo.get("price") + ""));
            item.setTitle((String)skuInfoVo.get("skuTitle"));

        }, executor);
        //2、查询当前商品的销售属性信息
        CompletableFuture<Void> saleInfoFuture = CompletableFuture.runAsync(()->{
            R attrValue = productFeignService.getSkuSaleAttrValue(skuId);
            List<String> attrSales = (List<String>) attrValue.get("skuSale");
            item.setSkuAttr(attrSales);
        },executor);

        CompletableFuture.allOf(skuInfoFuture,saleInfoFuture).get();
        //3、将购物详情添加到缓存中
        String itemString = JSON.toJSONString(item);
        operations.put(skuId+"",itemString);
        return item;
    }

    /**
     * 合并购物车
     * @return
     */
    @Override
    public Cart getCartItem() {

        UserInfoVo userInfoVo = CartInterceptor.threadLocal.get();
        List<CartItem> userLoginCart = new ArrayList<>();
        List<CartItem> userTempCart = new ArrayList<>();
        Cart cart = new Cart();
        //1、获取用户购物车列表（登录后）
        if(userInfoVo.getUserId() != null){
            userLoginCart = getCart(CART_PREFIX + userInfoVo.getUserId());
        }
        //2、获取用户临时购物车（没有登录时的购物项）
        if(!StringUtils.isEmpty(userInfoVo.getUserKey())){
            userTempCart = getCart(CART_PREFIX + userInfoVo.getUserKey());
        }
        //3、合并两个购物车信息
        if(userLoginCart == null || userLoginCart.size()==0){//用户登录购物车为空
            cart.setItmes(userTempCart);
        }

        if(userTempCart == null || userTempCart.size()==0){//用户临时购物车为空
            cart.setItmes(userLoginCart);
        }
        //都不为空，那么就合并两个购物车中的数据
        if(userLoginCart != null && userTempCart.size()>0 && userTempCart != null && userLoginCart.size()>0){
            for(int i = 0; i < userTempCart.size(); i++){
                CartItem tempCart = userTempCart.get(i);
                Long skuId = tempCart.getSkuId();
                for(CartItem loginCart : userLoginCart){
                    if(loginCart.getSkuId() == skuId){
                        loginCart.setCount(tempCart.getCount()+loginCart.getCount());
                        userTempCart.remove(tempCart);
                        break;
                    }
                }
            }
        }
        userLoginCart.addAll(userTempCart);
        cart.setItmes(userLoginCart);

        Long countNum = 0L;//商品总数
        int countType = 0;//类型总数
        BigDecimal totalAmount = new BigDecimal("0");//总价
        for(CartItem tempCart : userLoginCart){
           countNum += tempCart.getCount();
           totalAmount = totalAmount.add(tempCart.getTotalPrice());
        }
        cart.setCountNum(Integer.parseInt(countNum+""));
        cart.setCountType(userTempCart.size());
        cart.setTotalAmount(totalAmount);
        return cart;
    }

    /**
     * 修改购物车中购物项的选中状态
     * @param skuId
     * @param check
     */
    @Override
    public void checkItem(Long skuId, Boolean check) {
        BoundHashOperations<String, Object, Object> operations = getCart();
        String o = (String) operations.get(skuId.toString());
        if(!StringUtils.isEmpty(o)){
            CartItem item = JSON.parseObject(o, CartItem.class);
            item.setCheck(check);
            String jsonString = JSON.toJSONString(item);
            operations.put(skuId.toString(),jsonString);
        }
    }

    /**
     * 修改购物项数量
     * @param skuId
     * @param itemCount
     */
    @Override
    public void countItem(Long skuId, Integer itemCount) {
        BoundHashOperations<String, Object, Object> operations = getCart();
        String o = (String) operations.get(skuId.toString());
        if(!StringUtils.isEmpty(o)){
            CartItem item = JSON.parseObject(o, CartItem.class);
            item.setCount(itemCount);
            String jsonString = JSON.toJSONString(item);
            operations.put(skuId.toString(),jsonString);
        }
    }

    /**
     * 删除购物项
     * @param skuId
     */
    @Override
    public void deleteItem(Long skuId) {
        BoundHashOperations<String, Object, Object> operations = getCart();
        operations.delete(skuId.toString());
    }

    @Override
    public List<CartItem> getCartItems() {
        UserInfoVo userInfoVo = CartInterceptor.threadLocal.get();
        Long key = userInfoVo.getUserId();
        List<CartItem> cart = getCart(CART_PREFIX + key);
        return cart;
    }

    /**
     * 通过key获取购物车中的购物项信息
     * @param key
     * @return
     */
    private List<CartItem> getCart(String key) {
        BoundHashOperations<String, Object, Object> operations = stringRedisTemplate.boundHashOps(key);
        List<Object> values = operations.values();
        List<CartItem> userCart = values.stream().map(item -> {
            String cartItem = (String) item;
            CartItem item1 = JSON.parseObject(cartItem, CartItem.class);
            return item1;
        }).collect(Collectors.toList());
        return userCart;
    }

    /**
     * 获取我们需要操作的购物车
     * @return
     */
    private BoundHashOperations<String, Object, Object> getCart() {
        UserInfoVo userInfoVo = CartInterceptor.threadLocal.get();
        //1、判断用户是否已经登录
        String cartKey = "";
        if(userInfoVo.getUserId() != null){
            cartKey = CART_PREFIX + userInfoVo.getUserId();
        }else{//用户没有登录，使用临时用户信息
            cartKey = CART_PREFIX + userInfoVo.getUserKey();
        }
        //2、查看Redis中是否存在当前的商品，如果存在就改变数量
        BoundHashOperations<String, Object, Object> operations = stringRedisTemplate.boundHashOps(cartKey);
        return operations;
    }
}
